package com.cj.file.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.cj.common.config.handerconfig.IgnoreToken;
import com.cj.common.response.Result;
//import com.cj.common.utils.ExcelsUtil;
import com.cj.file.entity.DownloadData;
import com.cj.file.entity.UploadDAO;
import com.cj.file.entity.UploadData;
import com.cj.file.entity.UploadDataListener;
import com.cj.file.service.FileService;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.Numberings;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.data.Tables;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.util.PoitlIOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Author cheng jun
 * @Description:
 * @Date 2021/7/8 17:24
 */
@Controller
@RequestMapping(value = "/file")
public class FileController {

    /*@Resource
    private FileService localFileServiceImpl;*/
    @Resource
    private FileService onlineFileServiceImpl;

    @Autowired
    private UploadDAO uploadDAO;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE},
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public Result upload(@RequestPart(value = "file") MultipartFile file, HttpServletRequest request) {
        return Result.success(onlineFileServiceImpl.upLoad(file));
    }

    /**
     * 文件下载
     * @param map
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "/downLoad", method = RequestMethod.POST)
    public void download(@RequestBody Map<String, Object> map, HttpServletResponse response) {
        onlineFileServiceImpl.downLoad(map, response);
    }

    /**
     * 文件展示
     * @param map
     * @return
     */
    @RequestMapping(value = "/fileDisplay", method = RequestMethod.GET)
    @ResponseBody
    public Result fileDisplay(@RequestBody Map<String, Object> map) {
        return Result.success(onlineFileServiceImpl.fileDisplay(map));
    }

    /**
     * 文件删除
     * @param map
     * @return
     */
    @RequestMapping(value = "/fileDelete", method = RequestMethod.POST)
    @ResponseBody
    public Result fileDelete(@RequestBody Map<String, Object> map) {
        return Result.success(onlineFileServiceImpl.fileDelete(map));
    }

    /**
     * excel导出
     * @param request
     * @param response
     */
    @RequestMapping(value = "/excelExport", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreToken
    public void excelExport(HttpServletRequest request, HttpServletResponse response) {
//        ExcelsUtil.excelExport(request, response, ExcelsUtil.getData(), ".xlsx", "测试");
    }

    /**
     * excel导入
     */
    @RequestMapping(value = "/excelRead", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreToken
    public void excelRead(@RequestParam MultipartFile file) {
//        ExcelsUtil.excelRead(file);
    }

    /**
     * html转world导出
     * @param map
     * @param response
     */
    @RequestMapping(value = "/htmlToWorldExport", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreToken
    public void htmlToWorldExport(@RequestBody Map<String, Object> map, HttpServletResponse response) {
        onlineFileServiceImpl.htmlToWorldExport(map, response);
    }

    /**
     * world导出
     * @param map
     * @param response
     */
    @RequestMapping(value = "/worldExport", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreToken
    public void worldExport(@RequestBody Map<String, Object> map, HttpServletResponse response) {
        onlineFileServiceImpl.worldExport(map, response);
    }

    /**
     * 判断点是否在一个区域里
     * @param jd
     * @param wd
     */
    @RequestMapping(value = "/getIfInclude", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreToken
    public Result getIfInclude(String jd, String wd) {
        return Result.success(onlineFileServiceImpl.getIfInclude(jd, wd));
    }

    /**
     * shp文件导入并计算压盖面积
     * @param file
     */
    @RequestMapping(value = "/shpFileImportCalculate", method = {RequestMethod.POST})
    @IgnoreToken
    public Result shpFileImportCalculate(MultipartFile file) {
        return Result.success(onlineFileServiceImpl.shpFileImportCalculate(file));
    }

    /**
     * 文件下载（失败了会返回一个有部分数据的Excel）
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link DownloadData}
     * <p>
     * 2. 设置返回的 参数
     * <p>
     * 3. 直接写，这里注意，finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大
     */
    @GetMapping("download")
    public void download(HttpServletResponse response) throws IOException {
        // 单Sheet
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName= URLEncoder.encode("测试","UTF-8").replaceAll("\\+","%20");
        response.setHeader("Content-disposition","attachment;filename*=utf-8''"+fileName+".xlsx");
//        EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());


        // 多Sheet
        // 这里 指定文件
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build()) {
            // 去调用写入,这里我调用了五次，实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
            for (int i = 0; i < 5; i++) {
                // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变，我这里为了方便 所以用的同一个class
                // 实际上可以一直变
                WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DownloadData.class).build();
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                List<DownloadData> data = data();
                excelWriter.write(data, writeSheet);
            }
        }
    }

    /**
     * 文件上传
     * <p>1. 创建excel对应的实体对象 参照{@link UploadData}
     * <p>2. 由于默认一行行的读取excel，所以需要创建excel一行一行的回调监听器，参照{@link UploadDataListener}
     * <p>3. 直接读即可
     */
    @PostMapping("upload2")
    @ResponseBody
    public String upload(MultipartFile file)throws IOException{
        EasyExcel.read(file.getInputStream(), UploadData.class,new UploadDataListener(uploadDAO)).sheet().doRead();
        return"success";
    }

    private List<DownloadData> data() {
        List<DownloadData> list = ListUtils.newArrayList();
        for (int i = 0; i < 10; i++) {
            DownloadData data = new DownloadData();
            data.setString("字符串" + 0);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

    /**
     * Wold
     */
    @GetMapping("downloadWold")
    public void downloadWold(HttpServletResponse response) throws IOException {
        String classesPath = Objects.requireNonNull(this.getClass().getClassLoader().getResource("templates/template.docx")).getPath();
        XWPFTemplate template = XWPFTemplate.compile(classesPath.substring(1)).render(
                new HashMap<String, Object>(){{
                    // 文本
                    put("title", "Hi, poi-tl Word模板引擎");

                    // 图片
                    put("urlImg", Pictures.ofUrl("http://deepoove.com/images/icecream.png")
                            .size(100, 100).create());

                    // 一个2行2列的表格
                    put("table0", Tables.of(new String[][] {
                            new String[] { "00", "01" },
                            new String[] { "10", "11" },
                            new String[] { "12", "13" }
                    }).border(BorderStyle.DEFAULT).create());

                    // 列表
                    put("list", Numberings.create("Plug-in grammar",
                            "Supports word text, pictures, table...",
                            "Not just templates"));

                    // 区块对
                    List<Map<String,Object>> list = new ArrayList<>();
                    Map<String,Object> map1 = new HashMap<>();
                    map1.put("name", "Memories");
                    map1.put("name2", "Memories2");
                    Map<String,Object> map2 = new HashMap<>();
                    map2.put("name", "Sugar");
                    map2.put("name2", "Sugar2");
                    list.add(map1);
                    list.add(map2);
                    put("songs", list);
                }});
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment;filename*=utf-8''" + URLEncoder.encode("测试" + ".docx", "UTF-8"));

// HttpServletResponse response
        OutputStream out = response.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(out);
        template.write(bos);
        bos.flush();
        out.flush();
        PoitlIOUtils.closeQuietlyMulti(template, bos, out);
    }

    public static void main(String[] args) {
        FileController fileController = new FileController();
        fileController.getaaa();
    }

    public void getaaa() {
        String classesPath = Objects.requireNonNull(this.getClass().getClassLoader().getResource("templates/template.docx")).getPath();
        System.out.println("=============Constant.getPorjectPath()="+classesPath);
    }

}
